package com.snowj.apaas.service.impl;

import com.snowj.apaas.domain.auto.Agreements;
import com.snowj.apaas.domain.auto.Clients;
import com.snowj.apaas.repository.auto.AgreementsDynamicSqlSupport;
import com.snowj.apaas.repository.auto.AgreementsMapper;
import com.snowj.apaas.repository.auto.ClientsDynamicSqlSupport;
import com.snowj.apaas.repository.auto.ClientsMapper;
import com.snowj.apaas.security.SecurityConstants;
import com.snowj.apaas.security.SecurityUtils;
import com.snowj.apaas.service.AgreementService;
import com.snowj.apaas.web.vm.AgreementsVm;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.select.join.JoinCriterion;
import org.mybatis.dynamic.sql.where.condition.IsEqualTo;
import org.mybatis.dynamic.sql.where.condition.IsGreaterThanOrEqualTo;
import org.mybatis.dynamic.sql.where.condition.IsLessThanOrEqualTo;
import org.mybatis.dynamic.sql.where.condition.IsLike;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;



@Service
public class AgreementServiceImpl implements AgreementService {

    private final AgreementsMapper agreementsMapper;

    private final ClientsMapper clientsMapper;

    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    public AgreementServiceImpl(AgreementsMapper agreementsMapper, ClientsMapper clientsMapper) {
        this.agreementsMapper = agreementsMapper;
        this.clientsMapper = clientsMapper;
    }

    /**
     * 列出合同列表
     * 签约日期，客户名称，项目内容，商务人员，工程师，进度
     *
     * @param startDate
     * @param endDate
     * @param clientName
     * @param projectInfo
     * @param businessPeople
     * @param engineer
     * @param process
     * @param pageable
     * @return
     */
    @Override
    public Page<AgreementsVm> listAgreements(String startDate, String endDate, String clientName, String projectInfo,
                                           String businessPeople, String engineer, Integer process, Pageable pageable) {
        List<String> authorties = SecurityUtils.getCurrentUserAuthorties();

        Map<Long, String> clientsMap = clientsMapper.select(c -> c).stream()
                .collect(Collectors.toMap(Clients::getId, Clients::getName));

        List<AgreementsVm> agreementsVmList = agreementsMapper.select(c -> {
            // 添加权限信息
            if (!authorties.contains(SecurityConstants.ROLE_ADMIN)  && !authorties.contains(SecurityConstants.ROLE_ASSISTANT)) {
                String currentUser = SecurityUtils.getCurrentUserLogin();
                c.where(AgreementsDynamicSqlSupport.engineer, IsEqualTo.of(() -> currentUser));
            }
            if (startDate != null) {
                try {
                    Date start = dateFormat.parse(startDate);
                    c.where(AgreementsDynamicSqlSupport.signingDate, IsGreaterThanOrEqualTo.of(() -> start));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            if (endDate != null) {
                try {
                    Date end = dateFormat.parse(endDate);
                    c.where(AgreementsDynamicSqlSupport.signingDate, IsLessThanOrEqualTo.of(() -> end));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            if (!StringUtils.isEmpty(clientName)) {
                c.leftJoin(ClientsDynamicSqlSupport.clients)
                        .on(AgreementsDynamicSqlSupport.clientId, SqlBuilder.equalTo(ClientsDynamicSqlSupport.id))
                        .where(ClientsDynamicSqlSupport.name, IsLike.of(() -> "%" + clientName + "%"));
            }
            if (!StringUtils.isEmpty(projectInfo)) {
                c.where(AgreementsDynamicSqlSupport.projectInfo, IsLike.of(() -> "%" + projectInfo + "%"));
            }
            if (!StringUtils.isEmpty(businessPeople)) {
                c.where(AgreementsDynamicSqlSupport.businessPeople, IsLike.of(() -> "%" + businessPeople + "%"));
            }
            if (!StringUtils.isEmpty(engineer)) {
                c.where(AgreementsDynamicSqlSupport.engineer, IsLike.of(() -> "%" + engineer + "%"));
            }
            if (!StringUtils.isEmpty(process)) {
                c.where(AgreementsDynamicSqlSupport.process, IsEqualTo.of(() -> process));
            }
            c.offset((long) pageable.getPageSize() * pageable.getPageNumber());
            return c.limit(pageable.getPageSize());
        }).stream().map(agg -> {
            AgreementsVm agreementsVm = new AgreementsVm();
            BeanUtils.copyProperties(agg, agreementsVm);
            agreementsVm.setClientName(clientsMap.get(agreementsVm.getClientId()));
            if (!StringUtils.isEmpty(agg.getPassword())) {
                byte[] bytes = Base64.getDecoder().decode(agg.getPassword());
                String password = new String(bytes, StandardCharsets.UTF_8);
                agreementsVm.setPassword(password);
            }
            return agreementsVm;
        }).collect(Collectors.toList());

        long total = agreementsMapper.count(c -> {
            // 添加权限信息
            if (!authorties.contains(SecurityConstants.ROLE_ADMIN)  && !authorties.contains(SecurityConstants.ROLE_ASSISTANT)) {
                String currentUser = SecurityUtils.getCurrentUserLogin();
                c.where(AgreementsDynamicSqlSupport.engineer, IsEqualTo.of(() -> currentUser));
            }
            if (startDate != null) {
                try {
                    Date start = dateFormat.parse(startDate);
                    c.where(AgreementsDynamicSqlSupport.signingDate, IsGreaterThanOrEqualTo.of(() -> start));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            if (endDate != null) {
                try {
                    Date end = dateFormat.parse(endDate);
                    c.where(AgreementsDynamicSqlSupport.signingDate, IsLessThanOrEqualTo.of(() -> end));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            if (!StringUtils.isEmpty(clientName)) {
                JoinCriterion joinCriterion = new JoinCriterion.Builder()
                        .withJoinColumn(AgreementsDynamicSqlSupport.clientId)
                        .withConnector("on")
                        .withJoinCondition(SqlBuilder.equalTo(ClientsDynamicSqlSupport.id)).build();
                c.leftJoin(ClientsDynamicSqlSupport.clients, joinCriterion)
                        .where(ClientsDynamicSqlSupport.name, IsLike.of(() -> "%" + clientName + "%"));
            }
            if (!StringUtils.isEmpty(projectInfo)) {
                c.where(AgreementsDynamicSqlSupport.projectInfo, IsLike.of(() -> "%" + projectInfo + "%"));
            }
            if (!StringUtils.isEmpty(businessPeople)) {
                c.where(AgreementsDynamicSqlSupport.businessPeople, IsLike.of(() -> "%" + businessPeople + "%"));
            }
            if (!StringUtils.isEmpty(engineer)) {
                c.where(AgreementsDynamicSqlSupport.engineer, IsLike.of(() -> "%" + engineer + "%"));
            }
            if (!StringUtils.isEmpty(process)) {
                c.where(AgreementsDynamicSqlSupport.process, IsEqualTo.of(() -> process));
            }
            return c;
        });
        return new PageImpl<>(agreementsVmList, pageable, total);
    }

    /**
     * 根据编号查询合同
     *
     * @param id 合同编号
     * @return
     */
    @Override
    public Optional<Agreements> findAgreementsById(Long id) {
        List<String> authorties = SecurityUtils.getCurrentUserAuthorties();
        Optional<Agreements> agreementsOptional;
        // 添加权限信息
        if (!authorties.contains(SecurityConstants.ROLE_ADMIN)  && !authorties.contains(SecurityConstants.ROLE_ASSISTANT)) {
            agreementsOptional = agreementsMapper.selectOne(c -> {
                String currentUser = SecurityUtils.getCurrentUserLogin();
                c.where(AgreementsDynamicSqlSupport.id, IsEqualTo.of(() -> id))
                        .and(AgreementsDynamicSqlSupport.engineer, IsEqualTo.of(() -> currentUser));
                return c;
            });
        } else {
            agreementsOptional =  agreementsMapper.selectByPrimaryKey(id);
        }
        return agreementsOptional.map(agreements -> {
            if (!StringUtils.isEmpty(agreements.getPassword())) {
                byte[] bytes = Base64.getDecoder().decode(agreements.getPassword());
                String password = new String(bytes, StandardCharsets.UTF_8);
                agreements.setPassword(password);
            }
            return agreements;
        });
    }

    /**
     * 创建合同
     *
     * @param agreements 合同信息
     * @return
     */
    @Override
    public Agreements createAgreements(Agreements agreements) {
        if (agreements.getId() != null) {
            return null;
        }
        if (!StringUtils.isEmpty(agreements.getPassword())) {
            // 密码加密
            String encodedPassword = Base64.getEncoder().encodeToString(agreements.getPassword().getBytes(StandardCharsets.UTF_8));
            agreements.setPassword(encodedPassword);
        }
        agreements.setCreatedBy(SecurityUtils.getCurrentUserLogin());
        agreements.setCreatedDate(new Date());
        agreementsMapper.insert(agreements);
        return agreements;
    }

    /**
     * 更新合同
     *
     * @param agreements 合同信息
     * @return
     */
    @Override
    public Agreements updateAgreements(Agreements agreements) {
        if (agreements.getId() == null) {
            return null;
        }
        Optional<Agreements> savedAgreementsOptional = agreementsMapper.selectByPrimaryKey(agreements.getId());
        if (savedAgreementsOptional.isPresent()) {
            Agreements savedAgreements = savedAgreementsOptional.get();
//            agreements.setBusinessPeople(savedAgreements.getBusinessPeople());
//            agreements.setEngineer(savedAgreements.getEngineer());
            agreements.setCreatedBy(savedAgreements.getCreatedBy());
            agreements.setCreatedDate(savedAgreements.getCreatedDate());
            agreements.setLastModifiedBy(SecurityUtils.getCurrentUserLogin());
            agreements.setLastModifiedDate(new Date());
            if (!StringUtils.isEmpty(agreements.getPassword())) {
                // 密码加密
                String encodedPassword = Base64.getEncoder().encodeToString(agreements.getPassword().getBytes(StandardCharsets.UTF_8));
                agreements.setPassword(encodedPassword);
            }
            agreementsMapper.updateByPrimaryKey(agreements);
            return agreements;
        } else {
            return null;
        }
    }

    /**
     * 删除合同
     *
     * @param id 合同编号
     */
    @Override
    public void deleteAgreements(Long id) {
        agreementsMapper.deleteByPrimaryKey(id);
    }
}
